package com.firefly.app.biz.download;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.LinkedBlockingQueue;

public class SiteFileFetch extends Thread {
	
	public LinkedBlockingQueue<String> downloadQueue ;

	SiteInfoBean siteInfoBean = null; // 文件信息 Bean

	long[] nStartPos; // 开始位置

	long[] nEndPos; // 结束位置

	FileSplitterFetch[] fileSplitterFetch; // 子线程对象

	long nFileLength; // 文件长度

	boolean bFirst = true; // 是否第一次取文件

	boolean bStop = false; // 停止标志

	File tmpFile; // 文件下载的临时信息

	DataOutputStream output; // 输出到文件的输出流
	
	String fileName;
	
	String lastModifyTimeFromFile;//文件中保留的最后修改时间
	
	String lastModifyTimeCurr;//最新获取到的服务器最后修改时间
	
	long startTime;
	
	public SiteFileFetch(SiteInfoBean bean,LinkedBlockingQueue<String> downloadQueue) throws IOException {
		this.downloadQueue =downloadQueue;
		try {
			siteInfoBean = bean;
			// tmpFile = File.createTempFile ("zhong","1111",new File(bean.getSFilePath()));
			fileName =  bean.getSFilePath()+ File.separator +bean.getSFileName();
			tmpFile = new File(bean.getSFilePath() + File.separator + bean.getSFileName() + ".info");
			if (tmpFile.exists()) {
				bFirst = false;
				read_nPos();
				
				//如果不是第一次获取
				nFileLength = getFileSize();
				long nFileLengthFromFile = nEndPos[nEndPos.length - 1];
				//服务器返回长度和上一次获取长度不一致 或者 最后修改时间不一致，重新下载
				if (nFileLength != nFileLengthFromFile || lastModifyTimeFromFile.indexOf(lastModifyTimeCurr) <0) {
					Utility.log("断点续传发现不一致，将删除旧文件重新下载,原始文件长度："+nFileLengthFromFile+"新文件长度："+nFileLength+"原始文件修改时间："+lastModifyTimeFromFile+"新文件修改时间："+lastModifyTimeCurr);
					FileOperate.delTempFile(new File(fileName));
					FileOperate.delTempFile(tmpFile);
					nStartPos = new long[bean.getNSplitter()];
					nEndPos = new long[bean.getNSplitter()];
					bFirst = true;
				}
			} else {
				nStartPos = new long[bean.getNSplitter()];
				nEndPos = new long[bean.getNSplitter()];
			}
		} catch (Exception e) {
			e.printStackTrace();
			try {
				downloadQueue.put("fail");
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		}
	}

	public void run() {
		startTime = System.currentTimeMillis();
		// 获得文件长度
		// 分割文件
		// 实例 FileSplitterFetch
		// 启动 FileSplitterFetch 线程
		// 等待子线程返回
		try {
			if (bFirst) {
				nFileLength = getFileSize();
				if (nFileLength == -1 || nFileLength == 0) {
					Utility.log("文件长度未知，或者文件不存在。停止下载，退出。");
					throw new Exception("文件长度未知，或者文件不存在");
				} else if (nFileLength == -2) {
					Utility.log("File is not access!");
				} else {
					for (int i = 0; i < nStartPos.length; i++) {
						nStartPos[i] = (long) (i * (nFileLength / nStartPos.length));
					}
					for (int i = 0; i < nEndPos.length - 1; i++) {
						nEndPos[i] = nStartPos[i + 1];
					}
					nEndPos[nEndPos.length - 1] = nFileLength;
				}
			}
			
			
			// 启动子线程
			fileSplitterFetch = new FileSplitterFetch[nStartPos.length];
			for (int i = 0; i < nStartPos.length; i++) {
				fileSplitterFetch[i] = new FileSplitterFetch(siteInfoBean.getSSiteURL(), siteInfoBean.getSFilePath() + File.separator
						+ siteInfoBean.getSFileName(), nStartPos[i], nEndPos[i], i);
				Utility.log("Thread " + i + " , nStartPos = " + nStartPos[i] + ", nEndPos = " + nEndPos[i]);
				fileSplitterFetch[i].start();
			}
			// fileSplitterFetch[nPos.length-1] = new FileSplitterFetch(siteInfoBean.getSSiteURL(),
			// siteInfoBean.getSFilePath() + File.separator
			// + siteInfoBean.getSFileName(),nPos[nPos.length-1],nFileLength,nPos.length-1);
			// Utility.log("Thread " +(nPos.length-1) + ",nStartPos = "+nPos[nPos.length-1]+",
			// nEndPos = " + nFileLength);
			// fileSplitterFetch[nPos.length-1].start();
			// 等待子线程结束
			// int count = 0;
			// 是否结束 while 循环
			boolean breakWhile = false;
			while (!bStop) {
				write_nPos();
				Utility.sleep(500);
				breakWhile = true;
				for (int i = 0; i < nStartPos.length; i++) {
					if (!fileSplitterFetch[i].bDownOver) {
						breakWhile = false;
						break;
					}
				}
				if (breakWhile) break;
				// count++;
				// if(count>4)
				// siteStop();
			}
			long endTime = System.currentTimeMillis();
			
			FileOperate.renameFile(fileName);
			downloadQueue.put("true");
			Utility.log("文件下载结束！,本次用时"+(endTime - startTime) +"毫秒");
		} catch (Exception e) {
			e.printStackTrace();
			try {
				downloadQueue.put("fail");
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

	// 获得文件长度
	public long getFileSize()  throws Exception{
		int nFileLength = -1;
			URL url = new URL(siteInfoBean.getSSiteURL());
			HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
			httpConnection.setRequestProperty("User-Agent", "NetFox");
			httpConnection.setRequestProperty("Charset", "UTF-8"); 
			int responseCode = httpConnection.getResponseCode();
			if (responseCode >= 400) {
				processErrorCode(responseCode);
				return -2; // -2 represent access is error
			}
			
			lastModifyTimeCurr = httpConnection.getHeaderField("Last-Modified");
			String  contentLength = httpConnection.getHeaderField("Content-Length");
			nFileLength = Integer.parseInt(contentLength);
			if (lastModifyTimeCurr == null) {
				lastModifyTimeCurr = "server not Reply lastModifyTime";
			}
		Utility.log("服务器返回文件长度" +nFileLength);
		return nFileLength;
	}

	// 保存下载信息（文件指针位置）
	private void write_nPos() {
		try {
			output = new DataOutputStream(new FileOutputStream(tmpFile));
			output.writeInt(nStartPos.length);
			for (int i = 0; i < nStartPos.length; i++) {
				// output.writeLong(nPos[i]);
				output.writeLong(fileSplitterFetch[i].nStartPos);
				output.writeLong(fileSplitterFetch[i].nEndPos);
			}
			output.writeUTF(lastModifyTimeCurr);
			output.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 读取保存的下载信息（文件指针位置）
	private void read_nPos() {
		try {
			DataInputStream input = new DataInputStream(new FileInputStream(tmpFile));
			int nCount = input.readInt();
			nStartPos = new long[nCount];
			nEndPos = new long[nCount];
			for (int i = 0; i < nStartPos.length; i++) {
				nStartPos[i] = input.readLong();
				nEndPos[i] = input.readLong();
			}
			byte[] b = new byte[31];
			input.read(b);
			lastModifyTimeFromFile = new String(b,"utf-8");
			input.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void processErrorCode(int nErrorCode) {
		Utility.log("Error Code : " + nErrorCode);
	}

	// 停止文件下载
	public void siteStop() {
		bStop = true;
		for (int i = 0; i < nStartPos.length; i++)
			fileSplitterFetch[i].splitterStop();
	}
	
}
